/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jeuxEnConsole;

/**
 *
 * @author julien
 */
abstract public class NoeudAbstrait {

    protected PlateauCaracteres plateauCaracteres;
    protected int profondeur;
    protected int numJoueur;

    public NoeudAbstrait(PlateauCaracteres plateauCaracteres, int numJoueur, int profondeur) {
        this.plateauCaracteres = plateauCaracteres;
        this.profondeur = profondeur;
        this.numJoueur = numJoueur;
    }

    public PlateauCaracteres getPlateauCaracteres() {
        return plateauCaracteres;
    }

    abstract protected int getValeur();

    abstract public int getNbCoupsCalcules();
    
    public int calculeHeuristique(){
        //return (int) (Math.random()*10);
        
        int valeurHeuristique = 0;
        char[][] tabCaracteres = plateauCaracteres.getTabCaracteres();
        valeurHeuristique += calculAvantageMontagnes();
        //   System.out.println("Valeur heurisitique: " + valeurHeuristique);
        return valeurHeuristique;
    }
    
    
    static int pieceNeutre = 0;
    static int piecePousseMontagne = 1;
    static int pieceOpposePousseMontagne = -1;
    static int montagne = -1;
    static int avantagePiecePousseMontagneBonSens = 2;
    static int multiplicateurMontagneAvantBord = 2;
    static int multiplicateurMontagneBord = 5;
    
    private int calculAvantageMontagnes() {
        if (!plateauCaracteres.a3Montagnes()) {
            return 1000000;
        }
        int avantageMontagnes = 0;
        for (int i = 0; i < plateauCaracteres.largeurPlateau; i++) {
            for (int j = 0; j < plateauCaracteres.largeurPlateau; j++) {
                if (plateauCaracteres.tabCaracteres[i][j] == 'M') {
                    avantageMontagnes += calculAvantageMontagne(i, j);
                }
            }
        }

        return avantageMontagnes;
    }

    private int calculAvantageMontagne(int yMontagne, int xMontagne) {
        int valeurAvantageMontagne = 0;
        char[][] tabCaracteres = plateauCaracteres.getTabCaracteres();
        int largeurPlateau = plateauCaracteres.largeurPlateau;
        int multiplicateurMontagne = 1;

        if ((xMontagne >= 1 && xMontagne <= largeurPlateau - 2
                && (yMontagne == 1 || yMontagne == largeurPlateau - 2))
                || (yMontagne >= 1 && yMontagne <= largeurPlateau - 2
                && (xMontagne == 1 || xMontagne == largeurPlateau - 2))) {
            multiplicateurMontagne = multiplicateurMontagneAvantBord;
        } else if (xMontagne == 0 || xMontagne == largeurPlateau - 1
                || yMontagne == 0 || yMontagne == largeurPlateau - 1) {
            multiplicateurMontagne = multiplicateurMontagneBord;
        }

        if (tabCaracteres[yMontagne][xMontagne] == 'M') {

            int avantageDroit = calculAvantagePousseDroiteMontagne(xMontagne, yMontagne, xMontagne >= largeurPlateau - 2);
            int avantageGauche = calculAvantagePousseGaucheMontagne(xMontagne, yMontagne, xMontagne <= 2);
            int avantageHaut = calculAvantagePousseHautMontagne(xMontagne, yMontagne, yMontagne <= 2);
            int avantagebas = calculAvantagePousseBasMontagne(xMontagne, yMontagne, yMontagne >= largeurPlateau - 2);

            /*
            valeurAvantageMontagne = avantageDroit;
            if (Math.abs(avantageGauche) > Math.abs(avantageDroit)) {
                valeurAvantageMontagne = avantageGauche;
            }
            if (Math.abs(avantageHaut) > Math.abs(avantageGauche)) {
                valeurAvantageMontagne = avantageHaut;
            }
            if (Math.abs(avantagebas) > Math.abs(avantageHaut)) {
                valeurAvantageMontagne = avantagebas;
            }
            */
            
            valeurAvantageMontagne = avantageDroit + avantageGauche + avantageHaut + avantagebas;
        }
        return multiplicateurMontagne * valeurAvantageMontagne;
    }

    public int calculAvantagePousseDroiteMontagne(int xMontagne, int yMontagne, boolean bonCote) {

        if (xMontagne == 0) {
            return 0;
        }

        int valeurHeuristique = 0;

        int pn = pieceNeutre;
        int ppm = piecePousseMontagne;
        int popm = pieceOpposePousseMontagne;
        int m = montagne;


        char[][] tabCaracteres = plateauCaracteres.getTabCaracteres();
        int largeurPlateau = plateauCaracteres.largeurPlateau;
        if (bonCote) {
            ppm += avantagePiecePousseMontagneBonSens;
        }
        boolean avantageJoueur = true;
        for (int i = xMontagne - 1; i >= 0 && tabCaracteres[yMontagne][i] != 'X'; i--) {
            if (numJoueur == 1 && Character.isLowerCase(tabCaracteres[yMontagne][i])) {
                avantageJoueur = false;
                break;
            }
            if (numJoueur == 2 && Character.isUpperCase(tabCaracteres[yMontagne][i])
                    && tabCaracteres[yMontagne][i] != 'X'
                    && tabCaracteres[yMontagne][i] != 'M') {
                avantageJoueur = false;
                break;
            }
        }

        for (int i = xMontagne - 1; i >= 0; i--) {
            char piece = tabCaracteres[yMontagne][i];
            switch (piece) {
                case 'E':
                    valeurHeuristique += ppm;
                    break;
                case 'e':
                    valeurHeuristique += ppm;
                    break;
                case 'O':
                    for (int j = i - 1; j >= 0; j--) {
                        if(tabCaracteres[yMontagne][j] == 'E'
                        || tabCaracteres[yMontagne][j] == 'e')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'o':
                    for (int j = i - 1; j >= 0; j--) {
                        if(tabCaracteres[yMontagne][j] == 'E'
                        || tabCaracteres[yMontagne][j] == 'e')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'S':
                    valeurHeuristique += pn;
                    break;
                case 's':
                    valeurHeuristique += pn;
                    break;
                case 'N':
                    valeurHeuristique += pn;
                    break;
                case 'n':
                    valeurHeuristique += pn;
                    break;
                case 'M':
                    for (int j = i - 1; j >= 0; j--) {
                        if(tabCaracteres[yMontagne][j] == 'E'
                        || tabCaracteres[yMontagne][j] == 'e')
                            valeurHeuristique += m;
                    }
                    
//                    if (i >= 1) {
//                        if (tabCaracteres[yMontagne][i - 1] != 'X') {
//                            valeurHeuristique += m;
//                        }
//                    }
                    break;
                default:
                    break;
            }
        }

//        if (valeurHeuristique > 0 && !avantageJoueur) {
//            valeurHeuristique = -valeurHeuristique;
//        }

        return valeurHeuristique;

    }

    public int calculAvantagePousseGaucheMontagne(int xMontagne, int yMontagne, boolean bonCote) {

        if (xMontagne == plateauCaracteres.largeurPlateau - 1) {
            return 0;
        }

        int valeurHeuristique = 0;

        int pn = pieceNeutre;
        int ppm = piecePousseMontagne;
        int popm = pieceOpposePousseMontagne;
        int m = montagne;


        char[][] tabCaracteres = plateauCaracteres.getTabCaracteres();
        int largeurPlateau = plateauCaracteres.largeurPlateau;
        if (bonCote) {
            ppm += avantagePiecePousseMontagneBonSens;
        }
        boolean avantageJoueur = true;
        for (int i = xMontagne + 1; i < largeurPlateau && tabCaracteres[yMontagne][i] != 'X'; i++) {
            if (numJoueur == 1 && Character.isLowerCase(tabCaracteres[yMontagne][i])) {
                avantageJoueur = false;
                break;
            }
            if (numJoueur == 2 && Character.isUpperCase(tabCaracteres[yMontagne][i])
                    && tabCaracteres[yMontagne][i] != 'X'
                    && tabCaracteres[yMontagne][i] != 'M') {
                avantageJoueur = false;
                break;
            }
        }

        for (int i = xMontagne + 1; i < largeurPlateau; i++) {
            char piece = tabCaracteres[yMontagne][i];
            switch (piece) {
                case 'E':
                    for (int j = i + 1; j < largeurPlateau; j++) {
                        if(tabCaracteres[yMontagne][j] == 'o'
                        || tabCaracteres[yMontagne][j] == 'O')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'e':
                    for (int j = i + 1; j < largeurPlateau; j++) {
                        if(tabCaracteres[yMontagne][j] == 'o'
                        || tabCaracteres[yMontagne][j] == 'O')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'O':
                    valeurHeuristique += ppm;
                    break;
                case 'o':
                    valeurHeuristique += ppm;
                    break;
                case 'S':
                    valeurHeuristique += pn;
                    break;
                case 's':
                    valeurHeuristique += pn;
                    break;
                case 'N':
                    valeurHeuristique += pn;
                    break;
                case 'n':
                    valeurHeuristique += pn;
                    break;
                case 'M':
                    for (int j = i + 1; j < largeurPlateau; j++) {
                        if(tabCaracteres[yMontagne][j] == 'o'
                        || tabCaracteres[yMontagne][j] == 'O')
                            valeurHeuristique += m;
                    }
                    
//                    if (i < largeurPlateau - 1) {
//                        if (tabCaracteres[yMontagne][i + 1] != 'X') {
//                            valeurHeuristique += m;
//                        }
//                    }
                    break;
                default:
                    break;
            }
        }

//        if (valeurHeuristique > 0 && !avantageJoueur) {
//            valeurHeuristique = -valeurHeuristique;
//        }

        return valeurHeuristique;
    }

    public int calculAvantagePousseHautMontagne(int xMontagne, int yMontagne, boolean bonCote) {

        if (yMontagne == 0) {
            return 0;
        }

        int valeurHeuristique = 0;

        int pn = pieceNeutre;
        int ppm = piecePousseMontagne;
        int popm = pieceOpposePousseMontagne;
        int m = montagne;


        char[][] tabCaracteres = plateauCaracteres.getTabCaracteres();
        int largeurPlateau = plateauCaracteres.largeurPlateau;
        if (bonCote) {
            ppm += avantagePiecePousseMontagneBonSens;
        }
        boolean avantageJoueur = true;
        for (int i = yMontagne + 1; i < largeurPlateau && tabCaracteres[i][xMontagne] != 'X'; i++) {
            if (numJoueur == 1 && Character.isLowerCase(tabCaracteres[i][xMontagne])) {
                avantageJoueur = false;
            }
            if (numJoueur == 2 && Character.isUpperCase(tabCaracteres[i][xMontagne])
                    && tabCaracteres[i][xMontagne] != 'X'
                    && tabCaracteres[i][xMontagne] != 'M') {
                avantageJoueur = false;
            }
        }

        for (int i = yMontagne + 1; i < largeurPlateau; i++) {
            char piece = tabCaracteres[i][xMontagne];
            switch (piece) {
                case 'E':
                    valeurHeuristique += pn;
                    break;
                case 'e':
                    valeurHeuristique += pn;
                    break;
                case 'O':
                    valeurHeuristique += pn;
                    break;
                case 'o':
                    valeurHeuristique += pn;
                    break;
                case 'S':
                    for (int j = i + 1; j < largeurPlateau; j++) {
                        if(tabCaracteres[j][xMontagne] == 'N'
                        || tabCaracteres[j][xMontagne] == 'n')
                            valeurHeuristique += popm;
                    }
                    break;
                case 's':
                    for (int j = i + 1; j < largeurPlateau; j++) {
                        if(tabCaracteres[j][xMontagne] == 'N'
                        || tabCaracteres[j][xMontagne] == 'n')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'N':
                    valeurHeuristique += ppm;
                    break;
                case 'n':
                    valeurHeuristique += ppm;
                    break;
                case 'M':
                    for (int j = i + 1; j < largeurPlateau; j++) {
                        if(tabCaracteres[j][xMontagne] == 'N'
                        || tabCaracteres[j][xMontagne] == 'n')
                            valeurHeuristique += m;
                    }
//                    if (i < largeurPlateau - 1) {
//                        if (tabCaracteres[i + 1][xMontagne] != 'X') {
//                            valeurHeuristique += m;
//                        }
//                    }
                    break;
                default:
                    break;
            }
        }

//        if (valeurHeuristique > 0 && !avantageJoueur) {
//            valeurHeuristique = -valeurHeuristique;
//        }

        return valeurHeuristique;
    }

    public int calculAvantagePousseBasMontagne(int xMontagne, int yMontagne, boolean bonCote) {

        if (yMontagne == plateauCaracteres.largeurPlateau - 1) {
            return 0;
        }

        int valeurHeuristique = 0;

        int pn = pieceNeutre;
        int ppm = piecePousseMontagne;
        int popm = pieceOpposePousseMontagne;
        int m = montagne;


        char[][] tabCaracteres = plateauCaracteres.getTabCaracteres();
        int largeurPlateau = plateauCaracteres.largeurPlateau;
        if (bonCote) {
            ppm += avantagePiecePousseMontagneBonSens;
        }
        boolean avantageJoueur = true;
        for (int i = yMontagne - 1; i >= 0 && tabCaracteres[i][xMontagne] != 'X'; i--) {
            if (numJoueur == 1 && Character.isLowerCase(tabCaracteres[i][xMontagne])) {
                avantageJoueur = false;
            }
            if (numJoueur == 2 && Character.isUpperCase(tabCaracteres[i][xMontagne])
                    && tabCaracteres[i][xMontagne] != 'X'
                    && tabCaracteres[i][xMontagne] != 'M') {
                avantageJoueur = false;
            }
        }

        for (int i = yMontagne - 1; i >= 0; i--) {
            char piece = tabCaracteres[i][xMontagne];
            switch (piece) {
                case 'E':
                    valeurHeuristique += pn;
                    break;
                case 'e':
                    valeurHeuristique += pn;
                    break;
                case 'O':
                    valeurHeuristique += pn;
                    break;
                case 'o':
                    valeurHeuristique += pn;
                    break;
                case 'S':
                    valeurHeuristique += ppm;
                    break;
                case 's':
                    valeurHeuristique += ppm;
                    break;
                case 'N':
                    for (int j = i - 1; j >= 0; j--) {
                        if(tabCaracteres[j][xMontagne] == 'S'
                        || tabCaracteres[j][xMontagne] == 's')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'n':
                    for (int j = i - 1; j >= 0; j--) {
                        if(tabCaracteres[j][xMontagne] == 'S'
                        || tabCaracteres[j][xMontagne] == 's')
                            valeurHeuristique += popm;
                    }
                    break;
                case 'M':
                    for (int j = i - 1; j >= 0; j--) {
                        if(tabCaracteres[j][xMontagne] == 'S'
                        || tabCaracteres[j][xMontagne] == 's')
                            valeurHeuristique += m;
                    }
//                    if (i > 0) {
//                        if (tabCaracteres[i - 1][xMontagne] != 'X') {
//                            valeurHeuristique += m;
//                        }
//                    }
                    break;
                default:
                    break;
            }
        }

//        if (valeurHeuristique > 0 && !avantageJoueur) {
//            valeurHeuristique = -valeurHeuristique;
//        }

        return valeurHeuristique;
    }
    
    
}
